package data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Carrier {

    private static int carrierCounter;
    private String name;
    private List<Package> packages;
    private Map<String, Float> carriersWithCapacity;
    private float height, weight, capacity;
    private CarrierType type;

    /**
     * @param name
     * @param packages
     */
    public Carrier(CarrierType type) {
	carrierCounter++;
	this.type = type;
	this.name = "n" + carrierCounter;
	packages = new ArrayList<Package>();
	carriersWithCapacity = new HashMap<String, Float>();
    }

    public void pushPackage(Package pack) {
	Float capacityFromPrefferedCarrier = carriersWithCapacity.get(pack
		.getPrefferedCarrier());
	if (capacityFromPrefferedCarrier != null) {
	    carriersWithCapacity.put(pack.getPrefferedCarrier(),
		    capacityFromPrefferedCarrier + pack.getCapacity());
	} else {
	    carriersWithCapacity.put(pack.getPrefferedCarrier(),
		    pack.getCapacity());
	}

	packages.add(pack);
	weight += pack.getWeight();
	height += pack.getCapacity() / type.getFieldBase();
	capacity += pack.getCapacity();
    }

    public void popPackage(Package pack) {
	Float capacityFromPrefferedCarrier = carriersWithCapacity.get(pack
		.getPrefferedCarrier());
	carriersWithCapacity.put(pack.getPrefferedCarrier(),
		capacityFromPrefferedCarrier - pack.getCapacity());

	packages.remove(pack);
	weight -= pack.getWeight();
	height -= pack.getCapacity() / type.getFieldBase();
	capacity -= pack.getCapacity();
    }

    public void updateHeight() {
	height = 0;
	for (Package pack : packages) {
	    height += pack.getCapacity() / type.getFieldBase();
	}
    }

    public double getCapacityRoundToModules() {
	// jest pozno, nie mam lepszego pomyslu na policzenie tego xD
	int counter = 1;
	while (true) {
	    float minCapacityWithModulesCandidate = type.getModuleHeight()
		    * type.getFieldBase() * counter;
	    if (minCapacityWithModulesCandidate > this.capacity) {
		return minCapacityWithModulesCandidate;
	    }
	    counter++;
	}
    }

    /**
     * @return the carrierCounter
     */
    public static int getCarrierCounter() {
	return carrierCounter;
    }

    /**
     * @return the name
     */
    public String getName() {
	return name;
    }

    /**
     * @return the packages
     */
    public List<Package> getPackages() {
	return packages;
    }

    /**
     * @return the height
     */
    public float getHeight() {
	return height;
    }

    /**
     * @return the weight
     */
    public float getWeight() {
	return weight;
    }

    /**
     * @return the type
     */
    public CarrierType getType() {
	return type;
    }

    /**
     * @param type
     *            the type to set
     */
    public void setType(CarrierType type) {
	this.type = type;
	updateHeight();
    }

    /**
     * @return the capacity
     */
    public float getCapacity() {
	return capacity;
    }

    /**
     * @return the carriersWithCapacity
     */
    public Map<String, Float> getCarriersWithCapacity() {
	return carriersWithCapacity;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
	return "Carrier [name=" + name + ", packages=" + packages
		+ ", carriersWithCapacity=" + carriersWithCapacity
		+ ", height=" + height + ", weight=" + weight + ", capacity="
		+ capacity + ", type=" + type + "]";
    }
}
